package com.example.word.util;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;

import com.example.word.bean.Dict;
import com.example.word.bean.StudyPlan;
import com.example.word.bean.User;
import com.example.word.bean.Word;
import com.example.word.ui.activity.LoginActivity;
import com.example.word.ui.activity.MainActivity;
import com.example.word.ui.activity.UnitActivity;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import org.json.JSONObject;
import org.litepal.crud.DataSupport;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * http请求工具
 */
public class HttpUtils {

    /**
     * 服务器地址 建议使用 https
     */
    public static String serverUrl = "https://you.cn";

    /**
     * 服务端项目名
     */
    public static final String projectName = "/word-server";

    /**
     * 服务器文件下载地址
     */
    public static String downloadUrl = serverUrl + projectName + "/download?fileName=";

    /**
     * 服务器版本号
     */
    public static int version = 20231226;

    public static void test() {
//        Map<String, String> requestParam = new HashMap<>();
//        requestParam.put("account", "account");
//        // 调用 API 客户端的方法
//        HttpUtils.sendGetRequest("/userLogin", requestParam, activity, User.class, response -> {
//            User user = response.getData();
//        });
    }

    // 定义接口用于异步回调
    public interface ApiCallback<T> {
        void onSuccess(com.example.word.util.Response<T> response);

        default void onFailure(com.example.word.util.Response<T> response, Context activity) {
            // 处理请求失败的情况
            MessageUtils.show(response.getMsg(), activity);
            if (response.getCode() == 401) {
                activity.startActivity(new Intent(activity, LoginActivity.class));
            }
        }
    }

    // 定义接口用于异步回调
    public interface ApiStringCallback {
        void onSuccess(String responseString);
    }

    public static <T> void sendGetRequest(String uri, Map<String, String> params, Context activity, Class<T> clazz, ApiCallback<T> callback) {
        ProgressDialog dialog = new ProgressDialog(activity);
        if (!dialogShowing()) {
            dialog.setMessage("加载中···");
            dialog.setCancelable(false);
            dialog.show();
        }

        AsyncTask<Object, Void, com.example.word.util.Response<T>> asyncTask = new AsyncTask<Object, Void, com.example.word.util.Response<T>>() {

            @Override
            protected com.example.word.util.Response<T> doInBackground(Object... objects) {
                com.example.word.util.Response<T> responseObject = new com.example.word.util.Response<>();
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                // 设置连接超时时间，单位为秒
                builder.connectTimeout(6, java.util.concurrent.TimeUnit.SECONDS);
                // 设置读取超时时间，单位为秒
                builder.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS);
                // 设置写入超时时间，单位为秒
                builder.writeTimeout(30, java.util.concurrent.TimeUnit.SECONDS);
                OkHttpClient client = builder.build();

                // 构建请求URL，并添加查询参数
                HttpUrl.Builder urlBuilder = HttpUrl.parse(serverUrl + projectName + uri).newBuilder();
                String currentUserAccount = (String) SPUtils.get(activity, SPUtils.ACCOUNT, "");
                if (StringUtils.isNotEmpty(currentUserAccount)) {
                    urlBuilder.addQueryParameter("currentUserAccount", currentUserAccount);
                }
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
                }
                String url = urlBuilder.build().toString();

                Request request = new Request.Builder()
                        .url(url)
                        .build();

                int code = -1;
                try {
                    lock();
                    Log.d("HttpUtils", "开始请求 " + url);
                    Response response = client.newCall(request).execute();
                    code = response.code();

                    if (response.isSuccessful()) {
                        if (response.body() == null) {
                            responseObject.setCode(500);
                            responseObject.setMsg("服务器无响应");
                        } else {
                            String responseBody = response.body().string();
                            Log.d("HttpUtils", url + " 原始响应Body " + responseBody);
                            Gson gson = new GsonBuilder().setLenient().setPrettyPrinting().create();
                            Map<String, Object> json = gson.fromJson(responseBody, HashMap.class);
                            responseObject.setCode(Integer.parseInt(json.get("code").toString()));
                            responseObject.setMsg((String) json.get("msg"));
                            // 单独处理对象和数组的情况
                            try {
                                responseObject.setData(gson.fromJson(gson.toJson(json.get("data")), clazz));
                            } catch (Exception e) {
                                Log.d("HttpUtils", "解析data异常  " + e.getMessage());
                            }
                            try {
                                List<T> dataListCast = gson.fromJson(gson.toJson(json.get("data")), new TypeToken<List<T>>() {
                                }.getType());

                                List<T> dataList = new ArrayList<>(dataListCast.size());
                                for (T obj : dataListCast) {
                                    if (obj != null) {
                                        dataList.add(gson.fromJson(gson.toJson(obj), clazz));
                                    }
                                }
                                responseObject.setDataList(dataList);
                            } catch (Exception e) {
                                Log.d("HttpUtils", "解析dataList异常  " + e.getMessage());
                            }

                        }
                    } else {
                        responseObject.setCode(response.code());
                        responseObject.setMsg("服务请求失败(" + response.code() + ") " + response.message());

                        getServerUrl();
                    }
                } catch (Exception e) {
                    com.example.word.util.ExceptionUtils.printExceptionDetail(e);
                    responseObject.setCode(-1);
                    responseObject.setMsg("服务器异常(" + code + ") " + e.getMessage());

                    getServerUrl();
                } finally {
                    unlock();
                }

                responseObject.setActivity(activity);
                Log.d("HttpUtils", url + " 结束请求 " + responseObject);
                dialog.dismiss();
                return responseObject;
            }

            @Override
            protected void onPostExecute(com.example.word.util.Response<T> response) {
                if (response.getCode() == 200) {
                    callback.onSuccess(response);
                } else {
                    callback.onFailure(response, response.getActivity());
                }
            }
        };

        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public static <T> void uploadImage(String uri, File file, Context activity, Class<T> clazz, ApiCallback<T> callback) {
        ProgressDialog dialog = new ProgressDialog(activity);
        if (!dialogShowing()) {
            dialog.setMessage("加载中···");
            dialog.setCancelable(false);
            dialog.show();
        }

        AsyncTask<Object, Void, com.example.word.util.Response<T>> asyncTask = new AsyncTask<Object, Void, com.example.word.util.Response<T>>() {

            @Override
            protected com.example.word.util.Response<T> doInBackground(Object... objects) {
                com.example.word.util.Response<T> responseObject = new com.example.word.util.Response<>();
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                // 设置连接超时时间，单位为秒
                builder.connectTimeout(6, java.util.concurrent.TimeUnit.SECONDS);
                // 设置读取超时时间，单位为秒
                builder.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS);
                // 设置写入超时时间，单位为秒
                builder.writeTimeout(30, java.util.concurrent.TimeUnit.SECONDS);
                OkHttpClient client = builder.build();

                // 构建请求URL，并添加查询参数
                HttpUrl.Builder urlBuilder = HttpUrl.parse(serverUrl + projectName + uri).newBuilder();
                String currentUserAccount = (String) SPUtils.get(activity, SPUtils.ACCOUNT, "");
                if (StringUtils.isNotEmpty(currentUserAccount)) {
                    urlBuilder.addQueryParameter("currentUserAccount", currentUserAccount);
                }
                String url = urlBuilder.build().toString();

                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("file", file.getName(),
                                RequestBody.create(MediaType.parse("multipart/form-data"), file))
                        .build();
                Request request = new Request.Builder()
                        .url(url)
                        .post(requestBody)
                        .build();

                int code = -1;
                try {
                    lock();
                    Log.d("HttpUtils", "开始请求 " + url);
                    Response response = client.newCall(request).execute();
                    code = response.code();

                    if (response.isSuccessful()) {
                        if (response.body() == null) {
                            responseObject.setCode(500);
                            responseObject.setMsg("服务器无响应");
                        } else {
                            String responseBody = response.body().string();
                            Log.d("HttpUtils", url + " 原始响应Body " + responseBody);
                            Gson gson = new GsonBuilder().setLenient().setPrettyPrinting().create();
                            Map<String, Object> json = gson.fromJson(responseBody, HashMap.class);
                            responseObject.setCode(Integer.parseInt(json.get("code").toString()));
                            responseObject.setMsg((String) json.get("msg"));
                            // 单独处理对象和数组的情况
                            try {
                                responseObject.setData(gson.fromJson(gson.toJson(json.get("data")), clazz));
                            } catch (Exception e) {
                                Log.d("HttpUtils", "解析data异常  " + e.getMessage());
                            }
                            try {
                                List<T> dataListCast = gson.fromJson(gson.toJson(json.get("data")), new TypeToken<List<T>>() {
                                }.getType());

                                List<T> dataList = new ArrayList<>(dataListCast.size());
                                for (T obj : dataListCast) {
                                    if (obj != null) {
                                        dataList.add(gson.fromJson(gson.toJson(obj), clazz));
                                    }
                                }
                                responseObject.setDataList(dataList);
                            } catch (Exception e) {
                                Log.d("HttpUtils", "解析dataList异常  " + e.getMessage());
                            }

                        }
                    } else {
                        responseObject.setCode(response.code());
                        responseObject.setMsg("服务请求失败(" + response.code() + ") " + response.message());

                        getServerUrl();
                    }
                } catch (Exception e) {
                    com.example.word.util.ExceptionUtils.printExceptionDetail(e);
                    responseObject.setCode(-1);
                    responseObject.setMsg("服务器异常(" + code + ") " + e.getMessage());

                    getServerUrl();
                } finally {
                    unlock();
                }

                responseObject.setActivity(activity);
                Log.d("HttpUtils", url + " 结束请求 " + responseObject);
                dialog.dismiss();
                return responseObject;
            }

            @Override
            protected void onPostExecute(com.example.word.util.Response<T> response) {
                if (response.getCode() == 200) {
                    callback.onSuccess(response);
                } else {
                    callback.onFailure(response, response.getActivity());
                }
            }
        };

        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }


    public static void getServerUrl() {
        HttpUtils.sendGetRequestStringResponse("https://fccs-dsu.oss-cn-beijing.aliyuncs.com/dic/cpolar-server-url.txt?OSSAccessKeyId=LTAI4Fynb8gTQzm8hsZnYmBL&Expires=2223384874&Signature=yg%2BmxNrFRhnd9bPa4wdUfIVEGcU%3D", new HashMap<>(), responseString -> {
            serverUrl = responseString;
            downloadUrl = serverUrl + projectName + "/download?fileName=";
        });
    }

    public static void sendGetRequestStringResponse(String url, Map<String, String> params, ApiStringCallback callback) {
        AsyncTask<Object, Void, String> asyncTask = new AsyncTask<Object, Void, String>() {

            @Override
            protected String doInBackground(Object... objects) {
                OkHttpClient.Builder builder = new OkHttpClient.Builder();
                // 设置连接超时时间，单位为秒
                builder.connectTimeout(6, java.util.concurrent.TimeUnit.SECONDS);
                // 设置读取超时时间，单位为秒
                builder.readTimeout(15, java.util.concurrent.TimeUnit.SECONDS);
                // 设置写入超时时间，单位为秒
                builder.writeTimeout(15, java.util.concurrent.TimeUnit.SECONDS);
                OkHttpClient client = builder.build();

                // 构建请求URL，并添加查询参数
                HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
                }
                String url = urlBuilder.build().toString();

                Request request = new Request.Builder()
                        .url(url)
                        .build();

                try {
                    System.err.println(url + params);
                    Response response = client.newCall(request).execute();
                    String responseBody = response.body().string();
                    System.err.println(responseBody);

                    if (response.isSuccessful()) {
                        if (responseBody == null || "".equals(responseBody)) {
                            return "服务器无响应";
                        } else {
                            return responseBody;
                        }
                    } else {
                        return "服务器请求失败 " + response.code() + " " + response.body().string();
                    }
                } catch (Exception e) {
                    com.example.word.util.ExceptionUtils.printExceptionDetail(e);
                    return "连接服务器错误 " + e.getMessage();
                }
            }

            @Override
            protected void onPostExecute(String responseString) {
                callback.onSuccess(responseString);
            }
        };

        asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public static boolean dialogShowing = false;

    private synchronized static void unlock() {
        dialogShowing = false;
    }

    private synchronized static void lock() {
        dialogShowing = true;
    }

    private static synchronized boolean dialogShowing() {
        return dialogShowing;
    }

    private static final String testUrl = "http://192.168.2.65:8888";


}
